<template>
	<div class="windowListItem" :class="{ active: active }" ref="windowListItemRef" @click="onClick">
		<span class="order">{{ index + 1 }}</span>
		<canvas class="windowListItemCanvas" ref="canvasRef"></canvas>
	</div>
</template>

<script setup lang="ts">
/**
 * @Description: 多轴项目
 * @Author zcf
 * @Date 2023-10-13 09:55
 * @E-mail boyzcf@qq.com
 */
defineOptions({ name: 'WindowListItem' });
const props = withDefaults(
	defineProps<{
		index: number;
		data: Record<string, any>;
		totalMS: number;
		startTimestamp: number;
		width: number;
		active: boolean;
		multiSegmentActiveColor: string;
	}>(),
	{
		data: () => ({}),
		active: false,
		multiSegmentActiveColor: '#333',
	}
);
const emits = defineEmits(['click', 'click_window_timeSegments']);
const windowListItemRef = shallowRef();
const canvasRef = shallowRef();
const defaultData = reactive({
	height: 0,
	ctx: null as null | CanvasRenderingContext2D,
});

/**
 * @Desc: 初始化
 */
const init = () => {
	let { height } = windowListItemRef.value.getBoundingClientRect();
	defaultData.height = height - 1;
	canvasRef.value.width = props.width;
	canvasRef.value.height = defaultData.height;
	defaultData.ctx = canvasRef.value.getContext('2d');
};

/**
 * @Desc: 绘制时间段
 */
const drawTimeSegments = (callback?: (val: any) => void, path?: boolean) => {
	if (!props.data.timeSegments || props.data.timeSegments.length <= 0) {
		return;
	}
	const PX_PER_MS = props.width / props.totalMS; // px/ms，每毫秒占的像素
	props.data.timeSegments.forEach((item: any) => {
		if (item.beginTime <= props.startTimestamp + props.totalMS && item.endTime >= props.startTimestamp) {
			if (!defaultData.ctx) {
				throw new Error('canvas 未初始化');
			}
			defaultData.ctx.beginPath();
			let x = (item.beginTime - props.startTimestamp) * PX_PER_MS;
			let w;
			if (x < 0) {
				x = 0;
				w = (item.endTime - props.startTimestamp) * PX_PER_MS;
			} else {
				w = (item.endTime - item.beginTime) * PX_PER_MS;
			}
			let heightStartRatio = item.startRatio === undefined ? 0.6 : item.startRatio;
			let heightEndRatio = item.endRatio === undefined ? 0.9 : item.endRatio;
			if (path) {
				defaultData.ctx.rect(x, defaultData.height * heightStartRatio, w, defaultData.height * (heightEndRatio - heightStartRatio));
			} else {
				defaultData.ctx.fillStyle = item.color;
				defaultData.ctx.fillRect(x, defaultData.height * heightStartRatio, w, defaultData.height * (heightEndRatio - heightStartRatio));
			}
			callback && callback(item);
		}
	});
};
/**
 * @Desc: 清除画布
 */
const clearCanvas = () => {
	if (!defaultData.ctx) {
		throw new Error('canvas 未初始化');
	}
	defaultData.ctx.clearRect(0, 0, props.width, defaultData.height);
};

/**
 * @Desc: 绘制
 */
const draw = () => {
	nextTick(() => {
		clearCanvas();
		drawTimeSegments();
	});
};

/**
 * @Desc: 点击事件
 */
const onClick = (e: any) => {
	emits('click', e);
	let { left, top } = windowListItemRef.value.getBoundingClientRect();
	let x = e.clientX - left;
	let y = e.clientY - top;
	let timeSegments = getClickTimeSegments(x, y);
	if (timeSegments.length > 0) {
		emits('click_window_timeSegments', timeSegments, props.index, props.data);
	}
};
/**
 * @Desc: 检测当前是否点击了某个时间段
 */
const getClickTimeSegments = (x: number, y: number) => {
	if (!props.data.timeSegments || props.data.timeSegments.length <= 0) {
		return [];
	}
	let inItems: any[] = [];
	drawTimeSegments((item) => {
		if (defaultData.ctx && defaultData.ctx.isPointInPath(x, y)) {
			inItems.push(item);
		}
	}, true);
	return inItems;
};
/**
 * @Desc: 获取位置信息
 */
const getRect = () => {
	return windowListItemRef.value ? windowListItemRef.value.getBoundingClientRect() : null;
};
onMounted(() => {
	init();
	drawTimeSegments();
});

defineExpose({
	init,
	draw,
	getRect,
});
</script>

<style lang="scss" scoped>
.windowListItem {
	width: 100%;
	height: 30px;
	position: relative;
	border-bottom: 1px solid rgba(153, 153, 153, 1);
	user-select: none;

	&.active {
		background-color: v-bind(multiSegmentActiveColor);
	}

	.order {
		position: absolute;
		width: 30px;
		height: 30px;
		display: flex;
		justify-content: center;
		align-items: center;
		color: #fff;
		border-right: 1px solid rgba(153, 153, 153, 1);
	}
}
</style>
